"""
动态菜单生成器
用于生成Vue组件文件和路由配置
"""

import os
import re
from typing import Dict, Any
from django.conf import settings
import logging

logger = logging.getLogger(__name__)


class MenuGenerator:
    """菜单生成器类"""

    def __init__(self):
        """初始化生成器"""
        self.frontend_path = os.path.join(settings.BASE_DIR, '..', 'devops-frontend')
        self.generated_dir = os.path.join(self.frontend_path, 'src', 'views', 'generated')

    def generate_component_name(self, menu_name: str) -> str:
        """
        根据菜单名称生成组件名称

        Args:
            menu_name: 菜单名称

        Returns:
            组件名称
        """
        try:
            # 如果包含中文字符，尝试翻译成英文
            if re.search(r'[\u4e00-\u9fff]', menu_name):
                try:
                    from googletrans import Translator
                    translator = Translator()
                    result = translator.translate(menu_name, src='zh', dest='en')
                    english_name = result.text.replace(' ', '')
                    # 移除特殊字符，只保留字母数字
                    clean_name = re.sub(r'[^\w]', '', english_name)
                    if clean_name:
                        component_name = clean_name[0].upper() + clean_name[1:]
                    else:
                        component_name = 'GeneratedComponent'
                except:
                    # 翻译失败，使用哈希值确保唯一性
                    import hashlib
                    hash_value = hashlib.md5(menu_name.encode('utf-8')).hexdigest()[:8]
                    component_name = f'Page{hash_value.capitalize()}'
            else:
                # 不包含中文，直接处理
                clean_name = re.sub(r'[^\w]', '', menu_name)
                if clean_name:
                    component_name = clean_name[0].upper() + clean_name[1:]
                else:
                    component_name = 'GeneratedComponent'
        except Exception:
            component_name = 'GeneratedComponent'

        return component_name

    def generate_route_path(self, menu_name: str) -> str:
        """
        根据菜单名称生成路由路径（英文路径避免URL编码问题）
        使用和前端相同的中文到英文映射逻辑

        Args:
            menu_name: 菜单名称

        Returns:
            路由路径
        """
        # 使用和前端相同的中文到英文映射
        chinese_to_english = {
            '管理': 'management',
            '系统': 'system',
            '用户': 'user',
            '主机': 'host',
            '服务': 'service',
            '配置': 'config',
            '监控': 'monitor',
            '日志': 'log',
            '审计': 'audit',
            '权限': 'permission',
            '角色': 'role',
            '组': 'group',
            '菜单': 'menu',
            '设置': 'settings',
            '数据': 'data',
            '文件': 'file',
            '网络': 'network',
            '安全': 'security',
            '备份': 'backup',
            '报表': 'report',
            '任务': 'task',
            '项目': 'project',
            '资源': 'resource',
            '库存': 'inventory',
            '订单': 'order',
            '财务': 'finance',
            '星空': 'starry',
            '背景': 'background',
            '测试': 'test',
            '页面': 'page',
            '演示': 'demo',
            '展示': 'display',
            '分析': 'analysis'
        }

        english_name = menu_name
        for chinese, english in chinese_to_english.items():
            english_name = english_name.replace(chinese, english)

        # 移除非字母数字字符，转换为小写，用连字符连接
        english_name = re.sub(r'[^a-zA-Z0-9\u4e00-\u9fff]', '-', english_name)
        english_name = re.sub(r'[\u4e00-\u9fff]', '', english_name)  # 移除剩余中文
        english_name = re.sub(r'-+', '-', english_name)  # 合并多个连字符
        english_name = english_name.strip('-').lower()  # 移除首尾连字符并转小写

        if not english_name or len(english_name) < 2:
            english_name = 'custom-page'

        return english_name

    def generate_route_name(self, menu_name: str) -> str:
        """
        根据菜单名称生成路由名称（英文名称避免Vue Router问题）

        Args:
            menu_name: 菜单名称

        Returns:
            路由名称
        """
        # 使用相同的翻译逻辑，但首字母大写
        route_path = self.generate_route_path(menu_name)

        # 转换为驼峰命名
        parts = route_path.split('-')
        route_name = ''.join(word.capitalize() for word in parts)

        return route_name

    def delete_component_file(self, component_name: str) -> bool:
        """
        删除组件文件

        Args:
            component_name: 组件名称

        Returns:
            是否删除成功
        """
        try:
            file_path = os.path.join(self.generated_dir, f'{component_name}.vue')
            if os.path.exists(file_path):
                os.remove(file_path)
                logger.info(f"已删除组件文件: {file_path}")
                return True
            return False
        except Exception as e:
            logger.error(f"删除组件文件失败: {e}")
            return False

    def generate_placeholder_component(self, menu_data: Dict[str, Any]) -> str:
        """
        生成占位组件内容（使用星空背景和透明玻璃样式）

        Args:
            menu_data: 菜单数据

        Returns:
            Vue组件内容
        """
        component_name = menu_data['component_name']
        menu_name = menu_data['name']
        menu_icon = menu_data['icon']
        description = menu_data['description']

        # 生成完整的Vue组件内容
        template = f'''<template>
  <div class="ansible-audit-container">
    <!-- 星空背景 -->
    <div class="starry-background">
      <div class="stars"></div>
      <div class="stars2"></div>
      <div class="stars3"></div>
    </div>

    <!-- 主要内容区域 -->
    <div class="audit-content">
      <!-- 页面标题 -->
      <div class="page-header glass-effect">
        <div class="header-content">
          <div class="title-section">
            <h1 class="page-title">
              <i class="{menu_icon}"></i>
              {menu_name}
            </h1>
            <p class="page-subtitle">{description or '管理和配置' + menu_name + '相关功能'}</p>
          </div>
          <div class="stats-section">
            <div class="stat-card glass-effect">
              <div class="stat-number">{{{{ statistics.total_items || 0 }}}}</div>
              <div class="stat-label">总数</div>
            </div>
            <div class="stat-card glass-effect">
              <div class="stat-number">{{{{ statistics.active_items || 0 }}}}</div>
              <div class="stat-label">活跃</div>
            </div>
            <div class="stat-card glass-effect">
              <div class="stat-number">{{{{ statistics.success_rate || 0 }}}}%</div>
              <div class="stat-label">成功率</div>
            </div>
          </div>
        </div>
      </div>

      <!-- 操作按钮 -->
      <div class="search-filters glass-effect">
        <el-form inline class="search-form">
          <el-form-item>
            <el-button type="primary" @click="handleAdd" class="glass-button add-button" :loading="loading">
              <i class="fa fa-plus"></i>
              新增{menu_name}
            </el-button>
            <el-button @click="handleRefresh" class="glass-button refresh-button" :loading="loading">
              <i class="fa fa-refresh"></i>
              刷新数据
            </el-button>
            <el-button @click="handleExport" class="glass-button test-button">
              <i class="fa fa-download"></i>
              导出数据
            </el-button>
          </el-form-item>
        </el-form>
      </div>

      <!-- 数据列表 -->
      <div class="audit-table-section glass-effect">
        <div class="section-title">
          <i class="fa fa-list"></i>
          {menu_name}列表
        </div>

        <el-table
          :data="tableData"
          style="width: 100%"
          v-loading="loading"
          @row-click="viewDetail"
          row-class-name="audit-row"
          class="audit-table"
        >
          <el-table-column prop="id" label="ID" width="80" />
          <el-table-column prop="name" label="名称" min-width="150">
            <template #default="scope">
              <div class="config-name">
                <i class="{menu_icon}"></i>
                {{{{ scope.row.name }}}}
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="status" label="状态" width="100">
            <template #default="scope">
              <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'" size="small">
                {{{{ scope.row.status === 'active' ? '活跃' : '停用' }}}}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="created_at" label="创建时间" width="160">
            <template #default="scope">
              {{{{ formatTime(scope.row.created_at) }}}}
            </template>
          </el-table-column>
          <el-table-column label="操作" width="200" fixed="right">
            <template #default="scope">
              <div class="action-buttons">
                <el-button size="small" @click.stop="viewDetail(scope.row)" class="action-glass-button">
                  <i class="fa fa-eye"></i>
                  详情
                </el-button>
                <el-button size="small" @click.stop="editItem(scope.row)" class="action-glass-button">
                  <i class="fa fa-edit"></i>
                  编辑
                </el-button>
                <el-button
                  size="small"
                  @click.stop="deleteItem(scope.row)"
                  class="action-glass-button danger"
                >
                  <i class="fa fa-trash"></i>
                  删除
                </el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>

        <!-- 分页 -->
        <div class="pagination-container">
          <el-pagination
            v-model:current-page="pagination.currentPage"
            v-model:page-size="pagination.pageSize"
            :page-sizes="[10, 20, 50, 100]"
            :total="pagination.total"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </div>
    </div>
  </div>
</template>'''

        # JavaScript部分
        script_part = f'''

<script setup lang="ts">
import {{ ElMessage }} from 'element-plus'
import {{ onMounted, reactive, ref }} from 'vue'

// 响应式数据
const loading = ref(false)
const tableData = ref([])

// 统计数据
const statistics = ref({{
  total_items: 0,
  active_items: 0,
  success_rate: 0
}})

const pagination = reactive({{
  currentPage: 1,
  pageSize: 20,
  total: 0
}})

// 方法
const loadData = async () => {{
  loading.value = true
  try {{
    // TODO: 实现数据加载逻辑
    ElMessage.info('{menu_name}数据加载功能待开发')

    // 模拟数据
    tableData.value = [
      {{
        id: 1,
        name: '示例{menu_name}1',
        status: 'active',
        created_at: new Date().toISOString()
      }},
      {{
        id: 2,
        name: '示例{menu_name}2',
        status: 'inactive',
        created_at: new Date().toISOString()
      }}
    ]

    statistics.value = {{
      total_items: tableData.value.length,
      active_items: tableData.value.filter(item => item.status === 'active').length,
      success_rate: 95
    }}

    pagination.total = tableData.value.length
  }} catch (error) {{
    console.error('加载{menu_name}数据失败:', error)
    ElMessage.error('加载数据失败')
  }} finally {{
    loading.value = false
  }}
}}

const handleAdd = () => {{
  ElMessage.info('添加{menu_name}功能待开发')
}}

const handleRefresh = () => {{
  loadData()
}}

const handleExport = () => {{
  ElMessage.info('导出{menu_name}数据功能待开发')
}}

const viewDetail = (row) => {{
  ElMessage.info(`查看{menu_name}详情: ${{row.name}}`)
}}

const editItem = (row) => {{
  ElMessage.info(`编辑{menu_name}: ${{row.name}}`)
}}

const deleteItem = (row) => {{
  ElMessage.info(`删除{menu_name}: ${{row.name}}`)
}}

const formatTime = (dateTime) => {{
  if (!dateTime) return '无'
  try {{
    return new Date(dateTime).toLocaleString('zh-CN', {{
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit'
    }})
  }} catch (error) {{
    return dateTime
  }}
}}

const handleSizeChange = (size) => {{
  pagination.pageSize = size
  loadData()
}}

const handleCurrentChange = (page) => {{
  pagination.currentPage = page
  loadData()
}}

onMounted(() => {{
  console.log('{menu_name}页面已加载')
  loadData()
}})
</script>'''

        # 样式部分 - 完全复制Ansible配置管理的样式
        style_part = '''

<style lang="scss" scoped>
/* 主容器 */
.ansible-audit-container {
  position: relative;
  min-height: 100vh;
  background: linear-gradient(135deg,
    rgba(0, 0, 0, 0.9) 0%,
    rgba(20, 20, 40, 0.95) 50%,
    rgba(0, 0, 0, 0.9) 100%
  );
  overflow-x: hidden;
}

/* 星空背景 */
.starry-background {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

.stars, .stars2, .stars3 {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: transparent;
}

.stars {
  background-image:
    radial-gradient(2px 2px at 20px 30px, #eee, transparent),
    radial-gradient(2px 2px at 40px 70px, rgba(255,255,255,0.8), transparent),
    radial-gradient(1px 1px at 90px 40px, #fff, transparent);
  background-repeat: repeat;
  background-size: 200px 100px;
  animation: zoom 20s infinite linear;
}

.stars2 {
  background-image:
    radial-gradient(1px 1px at 40px 60px, #fff, transparent),
    radial-gradient(1px 1px at 120px 10px, rgba(255,255,255,0.7), transparent);
  background-repeat: repeat;
  background-size: 300px 200px;
  animation: zoom 40s infinite linear;
}

.stars3 {
  background-image:
    radial-gradient(1px 1px at 10px 10px, rgba(255,255,255,0.5), transparent);
  background-repeat: repeat;
  background-size: 400px 300px;
  animation: zoom 60s infinite linear;
}

@keyframes zoom {
  from { transform: scale(1); }
  to { transform: scale(1.5); }
}

/* 主要内容区域 */
.audit-content {
  position: relative;
  z-index: 10;
  padding: 20px;
  max-width: 1400px;
  margin: 0 auto;
}

/* 玻璃效果基础样式 */
.glass-effect {
  background: rgba(164, 244, 186, 0.1);
  border: 1px solid rgba(164, 244, 186, 0.2);
  border-radius: 12px;
  backdrop-filter: blur(20px);
  box-shadow:
    0 8px 32px rgba(0, 0, 0, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

/* 页面标题区域 */
.page-header {
  margin-bottom: 30px;
  padding: 30px;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 30px;
}

.title-section {
  flex: 1;
}

.page-title {
  color: #00eaff;
  font-size: 2.5em;
  margin: 0 0 10px 0;
  text-shadow: 0 0 20px rgba(0, 234, 255, 0.5);
  display: flex;
  align-items: center;
  gap: 15px;

  i {
    font-size: 0.8em;
  }
}

.page-subtitle {
  color: rgba(255, 255, 255, 0.7);
  font-size: 1.1em;
  margin: 0;
}

.stats-section {
  display: flex;
  gap: 20px;
}

.stat-card {
  padding: 20px;
  text-align: center;
  min-width: 120px;

  .stat-number {
    color: #00eaff;
    font-size: 2em;
    font-weight: bold;
    text-shadow: 0 0 10px rgba(0, 234, 255, 0.3);
  }

  .stat-label {
    color: rgba(255, 255, 255, 0.8);
    font-size: 0.9em;
    margin-top: 5px;
  }
}

/* 搜索和筛选 */
.search-filters {
  margin-bottom: 30px;
  padding: 20px;
}

.search-form {
  display: flex;
  align-items: center;
  gap: 15px;
}

/* 表格区域 */
.audit-table-section {
  margin-bottom: 30px;
  padding: 30px;
}

.section-title {
  color: #00eaff;
  font-size: 1.3em;
  margin-bottom: 20px;
  text-shadow: 0 0 10px rgba(0, 234, 255, 0.3);
  display: flex;
  align-items: center;
  gap: 10px;
}

.config-name {
  display: flex;
  align-items: center;
  gap: 8px;
  color: rgba(255, 255, 255, 0.9);

  i {
    color: #00eaff;
  }
}
</style>'''

        return template + script_part + style_part

    def generate_menu_data(self, name: str, parent_id=None, icon: str = 'fa-file', description: str = '') -> Dict[str, Any]:
        """
        生成菜单数据

        Args:
            name: 菜单名称
            parent_id: 父菜单ID
            icon: 图标
            description: 描述

        Returns:
            菜单数据字典
        """
        component_name = self.generate_component_name(name)
        route_path = self.generate_route_path(name)

        return {
            'name': name,
            'path': f'/{route_path}',
            'icon': icon,
            'description': description,
            'parent_id': parent_id,
            'component_name': component_name,
            'is_generated': True,
            'permission_code': f'{route_path}.view'
        }

    def create_component_file(self, menu_data: Dict[str, Any]) -> str:
        """
        创建组件文件

        Args:
            menu_data: 菜单数据

        Returns:
            创建的文件路径
        """
        component_content = self.generate_placeholder_component(menu_data)

        # 使用英文路由名称作为文件名，避免中文文件名问题
        route_name = self.generate_route_name(menu_data['name'])

        # 确定文件路径
        frontend_path = os.path.join(settings.BASE_DIR, '..', 'devops-frontend')
        generated_dir = os.path.join(frontend_path, 'src', 'views', 'generated')

        # 确保目录存在
        os.makedirs(generated_dir, exist_ok=True)

        # 写入文件，使用英文文件名
        file_path = os.path.join(generated_dir, f'{route_name}.vue')
        with open(file_path, 'w', encoding='utf-8') as f:
            f.write(component_content)

        return file_path
